#pragma once
#include "base/function.hpp"
#include "base/noncopyable.h"

#include <sys/epoll.h>
namespace net_tools{
class Eventloop;
namespace base{
class Epoll;
class Timeevent;
class Channel : noncopyable
{
friend class Epoll;
friend class Channelpool;
  public:
    Channel(Epoll* epoll);
    ~Channel();
    void Callback(int epoll_type);
    void Set_read_callback(func cb){read_callback_ = std::move(cb);};
    void Set_write_callback(func cb){write_callback_ = std::move(cb);};
    void Set_close_callback(func cb){close_callback_ = std::move(cb);};
    void Enableread(){epoll_type_ |= (EPOLLIN | EPOLLPRI | EPOLLRDHUP);Event_update();};
    void Disableread(){epoll_type_ &= ~(EPOLLIN | EPOLLPRI | EPOLLRDHUP);Event_update();};
    void Enablewrite(){epoll_type_ |= (EPOLLOUT);Event_update();};
    void Disablewrite(){epoll_type_ &= ~(EPOLLOUT);Event_update();};
    void Disableall(){epoll_type_ = 0;Event_update();};
    void Listenfd_init(int listenfd){listenfd_ = listenfd;};
    void Enable_ET(){epoll_type_ |= EPOLLET;Event_update();};
    void Disable_ET(){epoll_type_ &= ~EPOLLET;Event_update();};
    int Get_listenfd() const {return listenfd_;};
    void Add_to_epoll();
    void Mod_to_epoll();
    void Del_to_epoll();
  private:
    void Event_update(){event_.events = epoll_type_;};
    int         listenfd_;
    int         epoll_type_;
    func        read_callback_;
    func        write_callback_;
    func        close_callback_;
    epoll_event event_;
    Epoll*      epoll_;
};

} // namespace base
} // namespace net_tools